package com.papers.juan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.papers.common.core.domain.R;
import com.papers.common.exception.ServiceException;
import com.papers.common.helper.LoginHelper;
import com.papers.common.utils.StringUtils;
import com.papers.common.core.page.TableDataInfo;
import com.papers.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.papers.juan.domain.TJuanReposRelated;
import com.papers.juan.domain.bo.TJuanQuestionBo;
import com.papers.juan.domain.vo.*;
import com.papers.juan.mapper.TJuanReposRelatedMapper;
import com.papers.juan.service.ITJuanReposRelatedService;
import com.papers.system.mapper.TJuanKnowledgeMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.papers.juan.domain.bo.TJuanQuestionReposBo;
import com.papers.juan.domain.TJuanQuestionRepos;
import com.papers.juan.mapper.TJuanQuestionReposMapper;
import com.papers.juan.service.ITJuanQuestionReposService;
import org.springframework.transaction.annotation.Transactional;

import java.rmi.ServerException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 题库Service业务层处理
 *
 * @author papers
 * @date 2022-10-08
 */
@RequiredArgsConstructor
@Service
public class TJuanQuestionReposServiceImpl implements ITJuanQuestionReposService {

    private final TJuanQuestionReposMapper baseMapper;
    private final TJuanReposRelatedMapper tJuanReposRelatedMapper;

    /**
     * 查询题库
     */
    @Override
    public TJuanQuestionReposVo queryById(String reposId){
        return baseMapper.selectVoById(reposId);
    }

    /**
     * 查询题库列表
     */
    @Override
    public TableDataInfo<TJuanQuestionReposVo> queryPageList(TJuanQuestionReposBo bo, PageQuery pageQuery) {

        LambdaQueryWrapper<TJuanQuestionRepos> lqw = buildQueryWrapper(bo);
        Page<TJuanQuestionReposVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询题库列表
     */
    @Override
    public List<TJuanQuestionReposVo> queryList(TJuanQuestionReposBo bo) {
        LambdaQueryWrapper<TJuanQuestionRepos> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TJuanQuestionRepos> buildQueryWrapper(TJuanQuestionReposBo bo) {
        LambdaQueryWrapper<TJuanQuestionRepos> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), TJuanQuestionRepos::getOrgId, bo.getOrgId());
        lqw.like(StringUtils.isNotBlank(bo.getReposName()), TJuanQuestionRepos::getReposName, bo.getReposName());
        lqw.eq(StringUtils.isNotBlank(bo.getReposDes()), TJuanQuestionRepos::getReposDes, bo.getReposDes());
        lqw.eq(StringUtils.isNotBlank(bo.getReposCode()), TJuanQuestionRepos::getReposCode, bo.getReposCode());
        lqw.eq(StringUtils.isNotBlank(bo.getReposType()), TJuanQuestionRepos::getReposType, bo.getReposType());
        lqw.eq(StringUtils.isNotBlank(bo.getReposStatus()), TJuanQuestionRepos::getReposStatus, bo.getReposStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getCreatedBy()), TJuanQuestionRepos::getCreatedBy, bo.getCreatedBy());
        lqw.eq(bo.getCreatedTime() != null, TJuanQuestionRepos::getCreatedTime, bo.getCreatedTime());
        lqw.eq(StringUtils.isNotBlank(bo.getUpdatedBy()), TJuanQuestionRepos::getUpdatedBy, bo.getUpdatedBy());
        lqw.eq(bo.getUpdatedTime() != null, TJuanQuestionRepos::getUpdatedTime, bo.getUpdatedTime());
        return lqw;
    }

    /**
     * 新增题库
     */
    @Override
    public Boolean insertByBo(TJuanQuestionReposBo bo) {
        TJuanQuestionRepos add = BeanUtil.toBean(bo, TJuanQuestionRepos.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setReposId(add.getReposId());
        }
        return flag;
    }

    /**
     * 修改题库
     */
    @Override
    public Boolean updateByBo(TJuanQuestionReposBo bo) {
        TJuanQuestionRepos update = BeanUtil.toBean(bo, TJuanQuestionRepos.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TJuanQuestionRepos entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除题库
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public R getReposChart() {
        //获取当前用户
//        Long userId = 1L;
        Long userId = LoginHelper.getUserId();
        //查询该用户有多少题库
        if (null == userId) {
            return R.fail("系统异常，请联系管理员");
        }
        //总的统计数据
        List<ReposChart> data = new ArrayList<>();
        LambdaQueryWrapper<TJuanQuestionRepos> lqw = new LambdaQueryWrapper<>();
        List<TJuanQuestionRepos> reposList = baseMapper.selectList(lqw.eq(TJuanQuestionRepos::getCreatedBy, userId));
        for (TJuanQuestionRepos repos : reposList) {
            ReposChart chart = new ReposChart();
            chart.setName(repos.getReposName());
            List<QuestionChartVo> questions = baseMapper.getQuestionChart(repos.getReposId());
            chart.setCount(questions.size());
            //查字典，看有多少题目类型
            List<ReposChartChildren> topicChildren = baseMapper.getChildrenByDict("topic_type");
            //根据题目类型分组
            Map<String, List<QuestionChartVo>> groupTopic = questions.stream().collect(Collectors.groupingBy(QuestionChartVo::getQuestionType));
            for (ReposChartChildren topic : topicChildren) {
                topic.setCount(CollectionUtils.isNotEmpty(groupTopic.get(topic.getValue()))?groupTopic.get(topic.getValue()).size() : 0);
            }
            chart.setTopicTypeChildren(topicChildren);
            //查字典，看看有难度程度类型数zhepy
            List<ReposChartChildren> easyChildren = baseMapper.getChildrenByDict("difficulty");
            //根据难易程度分组
            Map<String, List<QuestionChartVo>> groupEasy = questions.stream().collect(Collectors.groupingBy(QuestionChartVo::getQuestionEasy));
            for (ReposChartChildren easy : easyChildren) {
                easy.setCount(CollectionUtils.isNotEmpty(groupEasy.get(easy.getValue()))?groupEasy.get(easy.getValue()).size() : 0);
            }
            chart.setDifficultyChildren(easyChildren);
            data.add(chart);
        }
        return R.ok(data);
    }

    @Override
    public R<Void> addRepos(TJuanQuestionReposBo bo) {
        bo.setCreatedTime(new Date());
        Long userId = LoginHelper.getUserId();
        bo.setCreatedBy(userId + "");
        //校验一下编码
        if (StringUtils.isBlank(bo.getReposCode())) {
            return R.fail("编码不能为空");
        }
        //校验编码是否已经存在
        LambdaQueryWrapper<TJuanQuestionRepos> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TJuanQuestionRepos::getReposCode, bo.getReposCode());
        TJuanQuestionRepos old = baseMapper.selectOne(lqw);
        if (null != old) {
            return R.fail("该编码已存在!");
        }
        TJuanQuestionRepos tJuanQuestionRepos = new TJuanQuestionRepos();
        BeanUtils.copyProperties(bo, tJuanQuestionRepos);
        baseMapper.insert(tJuanQuestionRepos);
        return R.ok("新增成功!");
    }

    /**
     * 合并题库
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int mergeRepos(TJuanQuestionReposBo bo, List<String> idList) {

        //创建新题库
        bo.setCreatedTime(new Date());
        Long userId = LoginHelper.getUserId();
        bo.setCreatedBy(userId + "");
        //校验一下编码
        if (null == bo.getReposCode()) {
            throw new ServiceException("编码不能为空");
        }
        //校验编码是否已经存在
        LambdaQueryWrapper<TJuanQuestionRepos> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TJuanQuestionRepos::getCreatedBy, userId).eq(TJuanQuestionRepos::getReposCode, bo.getReposCode());
        TJuanQuestionRepos old = baseMapper.selectOne(lqw);
        if (null != old) {
            throw new ServiceException("该编码已存在!");
        }
        TJuanQuestionRepos tJuanQuestionRepos = new TJuanQuestionRepos();
        BeanUtils.copyProperties(bo, tJuanQuestionRepos);
        baseMapper.insert(tJuanQuestionRepos);
        String reposId = tJuanQuestionRepos.getReposId();
        if(null == reposId){
            return 0;
        }
        //
        List<TJuanReposRelated> reposRelatedList = baseMapper.selectByReposId(idList);
        reposRelatedList.stream().forEach(x->x.setReposId(reposId));
        tJuanReposRelatedMapper.insertBatch(reposRelatedList);
        if(1 == bo.getType()){
            tJuanReposRelatedMapper.deleteByReposId(idList);
            //删除合并前题库
            baseMapper.deleteBatchIds(idList);
        }

        return 1;
    }

    @Override
    public R<Void> editRepos(TJuanQuestionReposBo bo) {
        Long userId = LoginHelper.getUserId();
        bo.setUpdatedBy(userId + "");
        bo.setUpdatedTime(new Date());
        if (StringUtils.isBlank(bo.getReposCode())) {
            return R.fail("编码不能为空");
        }
        TJuanQuestionRepos old = baseMapper.selectById(bo.getReposId());
        if (!bo.getReposCode().equals(old.getReposCode())) {
            //根据code去查询
            LambdaQueryWrapper<TJuanQuestionRepos> lqw = new LambdaQueryWrapper<>();
            lqw.eq(TJuanQuestionRepos::getReposCode, bo.getReposCode());
            TJuanQuestionRepos olds = baseMapper.selectOne(lqw);
            if (null != olds) {
                return R.fail("该编码已存在");
            }
        }
        TJuanQuestionRepos update = new TJuanQuestionRepos();
        BeanUtils.copyProperties(bo, update);
        baseMapper.updateById(update);
        return R.ok("更新成功!");
    }
}
